<?php

namespace app\api\logic\user;

use think\Db;
use think\facade\Request;
use app\common\access\Article as ArticleAccess;
use app\api\validate\Article as ArticleValidate;
use app\common\repository\user\R as UserRRepository;
use app\common\repository\article\C as ArticleCRepository;
use app\common\repository\article\U as ArticleURepository;
use app\common\repository\article\R as ArticleRRepository;
use app\common\repository\article\D as ArticleDRepository;
use app\common\repository\articleComment\C as ArticleCommentCRepository;
use app\common\repository\articleComment\R as ArticleCommentRRepository;
use app\common\repository\userStatistics\U as UserStatisticsURepository;

class UserArticle
{
    public function __construct(
        ArticleAccess $articleAccess,
        UserRRepository $userRRepository,
        ArticleCRepository $articleCRepository,
        ArticleURepository $articleURepository,
        ArticleRRepository $articleRRepository,
        ArticleDRepository $articleDRepository,
        ArticleCommentCRepository $articleCommentCRepository,
        ArticleCommentRRepository $articleCommentRRepository,
        UserStatisticsURepository $userStatisticsURepository
    )
    {
        $this->articleAccess = $articleAccess;
        $this->userRRepository = $userRRepository;
        $this->articleCRepository = $articleCRepository;
        $this->articleURepository = $articleURepository;
        $this->articleRRepository = $articleRRepository;
        $this->articleDRepository = $articleDRepository;
        $this->articleCommentCRepository = $articleCommentCRepository;
        $this->articleCommentRRepository = $articleCommentRRepository;
        $this->userStatisticsURepository = $userStatisticsURepository;
    }

    public function create()
    {
        $validate = new ArticleValidate;
        $articleEntity = ['user_id' => request()->user->id, 'title' => Request::param('title'), 'text' => Request::param('text')];
        $result = $validate->scene('create')->check($articleEntity);
        if ($result !== true) {
            return ['done' => false, 'code' => config('code.common.paramsRequire')];
        }
        Db::startTrans();
        try {
            $imgRe = '/\[.+?\]\((' . config('var.cdnBaseUrl') . '(.+?))\)/i';
            $tag = Request::param('tag');
            $type = Request::param('type');
            $know = Request::param('know');
            $source = Request::param('source');
            $goods = Request::param('goods');
            $sectionId = Request::param('section');
            if (preg_match($imgRe, $articleEntity['text'], $matches)) {
                $articleEntity['cover'] = $matches[2];
            }
            $article = $this->articleCRepository->create($articleEntity);
            if (!empty($tag)) {
                $article->tag()->saveAll(explode('|', $tag));
            }
            if (!empty($type)) {
                $article->type()->saveAll(explode('|', $type));
            }
            if (!empty($sectionId)) {
                $article->section()->save($sectionId);
            }
            $article->know()->saveAll($know);
            $article->source()->saveAll($source);
            $article->goods()->saveAll($goods);
            $this->userStatisticsURepository->doUserArticleByArticleId($article->id);
            Db::commit();
        } catch (\Exception $e) {
            Db::rollback();
        }
    }

    public function update()
    {
        $articleId = Request::param('id');
        $this->articleAccess->check($articleId);
        $validate = new ArticleValidate;
        $articleEntity = ['id' => $articleId, 'user_id' => request()->user->id, 'title' => Request::param('title'), 'text' => Request::param('text')];
        $result = $validate->scene('update')->check($articleEntity);
        if ($result !== true) {
            return ['done' => false, 'code' => config('code.common.paramsRequire')];
        }
        Db::startTrans();
        try {
            $imgRe = '/\[.+?\]\((' . config('var.cdnBaseUrl') . '(.+?))\)/i';
            $tag = Request::param('tag');
            $type = Request::param('type');
            $know = Request::param('know');
            $source = Request::param('source');
            $goods = Request::param('goods');
            $sectionId = Request::param('section');
            if (preg_match($imgRe, $articleEntity['text'], $matches)) {

                $articleEntity['cover'] = $matches[2];
            }
            $this->articleURepository->updateArticle($articleEntity, ['id' => $articleId]);
            if (!empty($tag)) {
                $this->articleURepository->updateArticleTag(explode('|', $tag), $articleId);
            }
            if (!empty($type)) {
                $this->articleURepository->updateArticleType(explode('|', $type), $articleId);
            }
            $this->articleURepository->updateArticleKnow($know, $articleId);
            $this->articleURepository->updateArticleSource($source, $articleId);
            $this->articleURepository->updateArticleGoods($goods, $articleId);
            $this->articleURepository->updateArticleSection($sectionId, $articleId);
            Db::commit();
        } catch (\Exception $e) {
            Db::rollback();
        }
    }

    public function get()
    {
        $articleId = Request::param('id');
        $this->articleAccess->check($articleId);
        if (!$articleId) {
            return ['done' => false, 'code' => config('code.common.paramsRequire')];
        }
        return ['data' => $this->articleRRepository->getArticle(['id' => $articleId])];
    }

    public function delete()
    {
        $this->articleDRepository->delete(Request::param('id'));
    }

    public function getArticles()
    {
        $pageIndex = Request::param('index');
        $pageSize = Request::param('size');
        if (!$pageIndex || !$pageSize) {
            return ['done' => false, 'code' => config('code.common.paramsRequire')];
        }
        $pageData = $this->articleRRepository->getArticlesWithPage(['user_id' => request()->user->id], [], ['index' => $pageIndex, 'size' => $pageSize]);
        return ['data' => $pageData['list'], 'page' => ['index' => $pageIndex, 'size' => $pageSize, 'count' => $pageData['count']]];
    }

    public function createArticleComment()
    {
        $userId = null;
        $guest = null;
        $articleId = Request::param('id');
        $validate = new ArticleValidate;
        $result = $validate->scene('createComment')->check(['comment' => Request::param('text')]);
        if ($result !== true) {
            return ['done' => false, 'code' => config('code.common.paramsRequire')];
        }
        if (!empty(request()->user)) {
            $userId = request()->user->id;
        } else {
            $guest = $this->userRRepository->getUser(['type' => 0]);
            $userId =  $guest->id;
        }
        $commentEntity = ['user_id' => $userId, 'refer_user_id' => Request::param('refer'), 'article_id' => $articleId, 'text' => Request::param('text')];
        $newComment = $this->articleCommentCRepository->createArticleComment($commentEntity);
        return ['data' => $this->articleCommentRRepository->getArticleComment(['id' => $newComment->id])];
    }

    public function doPraise()
    {
        $articleId = Request::param('id');
        if (!$articleId) {
            return ['done' => false, 'code' => config('code.common.paramsRequire')];
        }
        $this->articleURepository->doArticlePraise($articleId);
    }
}
